package uk.co.richardwkirk.parkrun.android.events.displays;

import java.util.ArrayList;
import java.util.Collections;

import uk.co.richardwkirk.parkrun.android.ActiveSelections;
import uk.co.richardwkirk.parkrun.android.AppSettings;
import uk.co.richardwkirk.parkrun.android.IntentExtras;
import uk.co.richardwkirk.parkrun.android.ParkrunEventData;
import uk.co.richardwkirk.parkrun.android.R;
import uk.co.richardwkirk.parkrun.android.SharedDataReadyActivity;
import uk.co.richardwkirk.parkrun.android.dataload.cache.AthleteCache;
import uk.co.richardwkirk.parkrun.android.events.distance.EventWithDistance;
import uk.co.richardwkirk.parkrun.android.events.distance.EventsWithDistanceComparator;
import uk.co.richardwkirk.parkrun.data.athletes.AthleteSummary;
import uk.co.richardwkirk.parkrun.data.events.Event;
import uk.co.richardwkirk.parkrun.geo.Region;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.Toast;

public class ClosestEvent extends SharedDataReadyActivity {

	private Region world = null;
	private Location lastLocation = null;
	
	ArrayList<EventWithDistance> eventGroups = new ArrayList<EventWithDistance>();
	ClosestEventExpandableListAdapter adapter;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.closest_event);
		
		// Get the selected athlete number from the intent
		if  (ActiveSelections.getSingleton().isAthleteSelected()) {
			// Have we already loaded the athlete?
			long selectedAthlete = ActiveSelections.getSingleton().getAthleteId();
			doAthleteLoad(selectedAthlete, false);
		}
		else {
			initialiseDisplay(null);
		}
	}

	
	private void initialiseDisplay(AthleteSummary athlete) {
		if (athlete == null) {
			this.setTitle("Closest events.");
		}
		else {
			this.setTitle("Closest events for " + athlete.getName() + ".");
		}
		
		// Get the world data
		Log.i("PARKRUN", "Getting event data for parkrun world.");
		world = ParkrunEventData.getSingleton().getWorld();
		if (world == null) {
			Toast toast = Toast.makeText(getApplicationContext(), "Could not get event details.", AppSettings.WARNING_DISPLAY_TIME);
			toast.show();
			finish();
		}
		else {
			// 	Create the list adapter
			Log.d("PARKRUN", "Setting up expandable list for closest events.");
			ExpandableListView listView = (ExpandableListView) findViewById(R.id.closest_event_list);
			adapter = new ClosestEventExpandableListAdapter(getApplicationContext(), eventGroups);
			listView.setAdapter(adapter);
			listView.setOnChildClickListener(myListItemClicked);
			showClosestEvents(world, athlete);
		}
	}


	private void showClosestEvents(Region world, AthleteSummary selectedAthlete) {
		Log.i("PARKRUN", "Getting location for closest event finder.");
		LocationManager locationManager;
        String context = Context.LOCATION_SERVICE;
        locationManager = (LocationManager)getSystemService(context);
        lastLocation = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
        
        Log.i("PARKRUN", "Showing distance to closest events.");
		if (world != null) {
			for (Event event : world.getAllEvents()) {
				eventGroups.add(EventWithDistance.create(event, lastLocation, selectedAthlete));
			}
			Collections.sort(eventGroups, new EventsWithDistanceComparator());
			adapter.notifyDataSetChanged();
		}
	}


	private void startEventDisplay(Event selectedEvent) {
		Intent intent = new Intent(this, EventDisplay.class);
		intent.putExtra(IntentExtras.EXTRA_SELECTED_EVENT, selectedEvent.getShortName());
		startActivity(intent);
	}
	
	
	public void showOnMap(View view) {
		EventDisplay.startRegionDisplay(this, world, lastLocation);	
	}

	void showEvent(EventWithDistance selectedEvent, int childPosition)
	{
		switch (childPosition) 
		{
			case 0:
				startEventDisplay(selectedEvent.getEvent());
				break;
			case 1:
				EventDisplay.startRegionDisplay(this, selectedEvent.getEvent().getRegion());
				break;
			case 3:
				navigateToEvent(selectedEvent.getEvent(), false);
				break;
			case 4:
				navigateToEvent(selectedEvent.getEvent(), true);
				break;
		}
	}
	
	private void navigateToEvent(Event event, boolean navigate) {
		String uri = null;
		String latlong = event.getLocation().getLatitude() + "," + event.getLocation().getLongitude();
		if (navigate) {
			uri = "google.navigation:q=" + latlong;
		}
		else {
			String query = latlong + "(" + event.getFullName() + ")";
			String encodedQuery = Uri.encode(query);
			uri = "geo:" + latlong + "?q=" + encodedQuery;
		}
		Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
		startActivity(browserIntent);
	}

	// our child listener
	private OnChildClickListener myListItemClicked = new OnChildClickListener() {

		public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
			EventWithDistance selectedEvent = (EventWithDistance) adapter.getGroup(groupPosition);
			showEvent(selectedEvent, childPosition);
			return true;
		}

	};

	@Override
	protected void handleEventLoadResponse(int requestCode) {
		// TODO Auto-generated method stub
		
	}

	@Override
	protected void handleCountrySelectionResult(int requestCode, Intent data) {
		// Country selection not used.
	}

	@Override
	protected void handleAthleteLoadResponse(int requestCode) {
		// We have received the news feed data load response.
		AthleteSummary athleteData = AthleteCache.getSingleton().getItem(String.valueOf(ActiveSelections.getSingleton().getAthleteId()));
		if (athleteData == null) {
			Toast toast = Toast.makeText(getApplicationContext(), "Could not load selected athlete.", AppSettings.WARNING_DISPLAY_TIME);
			toast.show();
		}
		initialiseDisplay(athleteData);
	}


	@Override
	protected void handleDataLoadError(int requestCode) {
		finish();
	}


	@Override
	protected void handleDataLoadCancel(int requestCode) {
		finish();
	}
	
}
